package com.heima.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.search.service.ApUserSearchService;
import com.heima.search.service.ArticleSearchService;
import com.heima.utils.threadlocal.AppThreadLocalUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ArticleSearchServiceImpl implements ArticleSearchService {

    @Autowired
    RestHighLevelClient restHighLevelClient;
    @Autowired
    ApUserSearchService apUserSearchService;
    /**
     * ES文章分页搜索
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult search(UserSearchDto dto) {
        //边界条件  无需登录  不能查询空值  size要合法
        String searchWords = dto.getSearchWords();
        if (dto==null || StringUtils.isBlank(searchWords)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (dto.getPageSize()<1 || dto.getPageSize()>10){
            dto.setPageSize(8);
        }
        //************如果是首页记录搜索关键字************
        ApUser user = AppThreadLocalUtils.getUser();
        if (user!=null && dto.getFromIndex()==0 && user.getId()!=null){
            dto.setEntryId(user.getId());
            //异步保存记录
            apUserSearchService.insert(dto);
        }
        //构建查询条件,  构建高亮三要素,  查询构造器
        BoolQueryBuilder queryBuilder=QueryBuilders.boolQuery()
                .must(QueryBuilders.matchQuery("title",searchWords))
                .filter(
                        QueryBuilders.rangeQuery("publishTime")
                        .lt(dto.getMinBehotTime().getTime())
                );
        HighlightBuilder highlightBuilder = SearchSourceBuilder.highlight()
                .field("title")
                .preTags("<font style=\"color:red\">")
                .postTags("</font>");
        SearchSourceBuilder sourceBuilder=SearchSourceBuilder.searchSource()
                .from(0).size(dto.getPageSize())
                .sort("publishTime", SortOrder.DESC)
                .highlighter(highlightBuilder)
                .query(queryBuilder);
        //构建查询请求
        SearchRequest request = new SearchRequest("app_info_article");
        request.source(sourceBuilder);

        //发送查询请求，获取响应，解析结果
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            SearchHits searchHits = response.getHits();
            long total= searchHits.getTotalHits().value;
            log.info("总条数:{}",total);
            SearchHit[] hits = searchHits.getHits();

            List<Map> resultList=new ArrayList<>();
            for (SearchHit hit : hits) {
                String sourceAsString = hit.getSourceAsString();
                Map article = JSON.parseObject(sourceAsString, Map.class);

                //获取高亮结果
                Text[] titles = hit.getHighlightFields().get("title").getFragments();
                //保留原始结果
                article.put("o_title",article.get("title"));
                String title = StringUtils.join(titles);
                if (StringUtils.isNotBlank(title)){
                    article.put("title",title);
                }
                resultList.add(article);
            }
            return ResponseResult.okResult(resultList);

        } catch (IOException e) {
            e.printStackTrace();
            log.info("es error:{}",e);
        }

        return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
    }
}
